home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / ZIPPED / DOS / GRAPHICS / POVSRC.ZIP / MACHINE.ZIP / MAC.SIT / textEditor.c < prev    next >
Text File  |  1992-05-05  |  16KB  |  765 lines

  1. // MPW Conversion 3/17/92  Eduard [esp] Schwan
  2. // Added MPW include headers, changed ALL the necessary 'int's
  3. // to 'short's (frefs and vrefs), pulled out the prototypes
  4. // into a separate TextEditor.h file for POV.C to see, added
  5. // needed type casts, added "qd." suffix on qd globals, ..
  6. //    whew.. looks like this used to be a Think C 4.0 thingie
  7. //  (It was.  jln)
  8. /*------------------------------------------------------------------------------
  9. Copyright 1992 POV-Team.
  10.     This source code is distributed exclusively with POV, and is subject to
  11.     the same distribution restrictions as the rest of the source code.
  12.  
  13. *  Copying, distribution and legal info is in the file povlegal.doc which
  14. *  should be distributed with this file. If povlegal.doc is not available
  15. *  or for more information please contact:
  16. *
  17. *       Drew Wells [POV-Team Leader] 
  18. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  19. *       Phone: (213) 254-4041
  20. * ----------------------------------------------------------------------------*/
  21.  
  22. #include <types.h>        // basic types
  23. #include <desk.h>        // SystemEdit, etc.
  24. #include <errors.h>        // noErr, etc.
  25. #include <files.h>        // FSOpen, etc. 
  26. #include <fonts.h>        // monaco, etc. 
  27. #include <memory.h>        // NewHandle, etc. 
  28. #include <menus.h>        // MenuHandle, etc. 
  29. #include <packages.h>    // SFGetFile, etc. 
  30. #include <scrap.h>        // ZeroScrap, etc. 
  31. #include <toolutils.h>    // watchCursor, etc. 
  32. #include <windows.h>    // SizeWindow, etc. 
  33. #include <stdio.h>
  34. #include <PrintTraps.h>
  35.  
  36. #include "config.h"
  37. #include "POVMac.h"
  38.  
  39. extern prefs_ptr_t    file_settings;    // changed [esp]
  40. extern int    POV_running;    /* Used to determine the menu states. */
  41.  
  42. WindowRecord    wRecord;
  43. WindowPtr        TextEditWindow;
  44. TEHandle        TEH;
  45. int                linesInFolder;
  46. Rect            dragRect = { 0, 0, 1024, 1024 };
  47. MenuHandle        myEditMenus[3];
  48. ControlHandle     vScroll;
  49. Cursor            editCursor;
  50. Cursor            waitCursor;
  51. char            dirty;
  52. char            window_visible;
  53.  
  54.  
  55. Str255         theFileName;
  56. short            theVRefNum;
  57.  
  58.  
  59. int SetUpFiles(void)
  60. {
  61.     pStrCopy("\p", theFileName);
  62.     theVRefNum = 0;
  63.     return 0; // should be void fn!?
  64. }
  65.  
  66.  
  67. int DoFile (int item)
  68.  
  69. {
  70.     short     vRef, refNum;
  71.     Str255    fn;
  72.  
  73.     switch (item) {
  74.  
  75.         case fmn_open:
  76.             HideWindow(TextEditWindow);    /* gives a sense of closing the old file. */
  77.             if (OldFile(fn, &vRef ))
  78.                 if (FSOpen(fn, vRef, &refNum)==noErr) {
  79.                     if (ReadFile(refNum, TEH)) {
  80.                         pStrCopy(fn, theFileName);
  81.                         theVRefNum = vRef;
  82.                         SetWTitle(TextEditWindow, theFileName);
  83.                         dirty = 0;
  84.                     }
  85.                     if (FSClose(refNum)==noErr) ;
  86.                     ShowWindow(TextEditWindow);
  87.                     window_visible = TRUE;
  88.                     TESetSelect(0, 0, TEH);
  89.                     ShowSelect();
  90.                 }
  91.                 else FileError("\pError opening ", fn);
  92.             break;
  93.  
  94.         case fmn_close:
  95.             DoFile(fmn_render);    // recurse.
  96.             CloseMyWindow();
  97.             break;
  98.  
  99.         case fmn_render:
  100.             if (dirty) {
  101.                 ParamText("\pSave changes to ╥",
  102.                         (theFileName[0]==0) ? "\pUntitled" : theFileName,
  103.                         "\p╙?", "\p");
  104.                 switch (Alert(AdviseAlert, 0L)) {
  105.                 case aaSave:
  106.                     if (theFileName[0]==0) {
  107.                         fn[0] = 0;
  108.                         if (!SaveAs(fn, &vRef)) return(0);
  109.                     }
  110.                      else if (!SaveFile(theFileName, theVRefNum)) return(0);
  111.                      break;
  112.                  case aaCancel: return(0);
  113.                  case aaDiscard: dirty = 0;
  114.                  }
  115.              }
  116.             break;
  117.         case fmn_savetext:
  118.             if (theFileName[0]==0) goto saveas;
  119.             SaveFile(theFileName, theVRefNum);
  120.             break;
  121.         case fmn_saveas:
  122.     saveas:
  123.             fn[0] = 0;
  124.             if (SaveAs(fn, &vRef )) {
  125.                 pStrCopy(fn, theFileName);
  126.                 theVRefNum = vRef;
  127.                 SetWTitle(TextEditWindow, theFileName);
  128.             }
  129.             break;
  130.         case fmRevert:
  131.             ParamText("\pRevert to last saved version of ╥",
  132.                     theFileName, "\p╙?", "\p");
  133.             switch (Alert(AdviseAlert, 0L)) {
  134.             case aaSave:
  135.                 HidePen();
  136.                 TESetSelect(0, (**TEH).teLength, TEH);
  137.                 ShowPen();
  138.                 TEDelete(TEH);
  139.                 if ((theFileName[0]!=0) &&
  140.                     (FSOpen(theFileName, theVRefNum, &refNum)==noErr)) {
  141.                     dirty = !ReadFile(refNum, TEH); 
  142.                     if (FSClose(refNum)==noErr) ;
  143.                 }
  144.                 ShowWindow(TextEditWindow);
  145.                 window_visible = TRUE;
  146.                 UpdateWindow(TextEditWindow);
  147.              case aaCancel:
  148.              case aaDiscard: return(0);;
  149.              }
  150.     
  151.             break;
  152.         case fmPageSetUp:
  153.             DoPageSetUp();
  154.             break;
  155.         case fmPrint:
  156.             PrintText( (**TEH).hText, (long)(**TEH).teLength, (GrafPtr)TextEditWindow,
  157.                             StringWidth("\pmmmm"));
  158.             break;
  159.         case fmQuit: 
  160.             if (DoFile(fmn_close))
  161.                 ExitToShell();
  162.     }
  163.     return(1);
  164. }
  165.  
  166. static Point SFGwhere = { 90, 82 };
  167. static Point SFPwhere = { 106, 104 };
  168. static SFReply reply;
  169.  
  170. int SaveAs (Str255 fn, short *vRef)
  171.  
  172. {
  173.     short refNum;
  174.     
  175.     if (NewFile(fn, vRef)) 
  176.         if (!CreateFile(fn, vRef, &refNum)) {
  177.             FileError("\pError creating file ", fn);
  178.             return (0);
  179.         } else {
  180.             HLock((**TEH).hText);
  181.             if (WriteFile(refNum, (*(**TEH).hText), (long)(**TEH).teLength))
  182.                 FileError("\pError writing file ", fn);
  183.             HUnlock((**TEH).hText);
  184.             FSClose(refNum);
  185.             dirty = 0;
  186.             return(1);
  187.         }
  188. }
  189.  
  190. int SaveFile (Str255 fn, short vrn)
  191.  
  192. {
  193.     short refNum;
  194.     if (FSOpen(fn, vrn, &refNum) != noErr) {
  195.         FileError("\pError opening file ", fn);
  196.         return (1);
  197.     } else {
  198.         HLock((**TEH).hText);
  199.         if (WriteFile(refNum, (*(**TEH).hText), (long)(**TEH).teLength))
  200.             FileError("\pError writing file ", fn);
  201.         HUnlock((**TEH).hText);
  202.         dirty = 0;
  203.         FSClose(refNum);
  204.         return(1);
  205.     }
  206. }
  207.  
  208. int NewFile (Str255 fn, short *vRef)
  209.  
  210. {
  211.     SFPutFile(SFPwhere, "\pSave file as", fn, 0L, &reply);
  212.     if (!reply.good)
  213.         return (0);
  214.     else {
  215.         pStrCopy(reply.fName, fn);
  216.         *vRef = reply.vRefNum;
  217.         return(1);
  218.     }
  219. }
  220.  
  221. int OldFile (Str255 fn, short *vRef)
  222.  
  223. {
  224.     SFTypeList    myTypes;
  225.     
  226.     myTypes[0]='TEXT';
  227.  
  228.     SFGetFile(SFGwhere, "\p", 0L, 1, myTypes, 0L, &reply );
  229.  
  230.     if (!reply.good)
  231.         return (0);
  232.     else {
  233.         pStrCopy(reply.fName, fn);
  234.         *vRef = reply.vRefNum;
  235.         return(1);
  236.     }
  237. }
  238.  
  239. int CreateFile (Str255 fn, short *vRef, short *theRef)
  240.  
  241. {
  242.     OSErr io;
  243.     
  244.     io=Create(fn, *vRef, kAppSignature, 'TEXT');    // changed [esp]
  245.     if ((io == noErr) || (io == dupFNErr))
  246.         io = FSOpen(fn, *vRef, theRef );
  247.  
  248.     return ((io == noErr) || (io == dupFNErr));
  249. }
  250.  
  251. int WriteFile (short refNum, char *p, long num)
  252.  
  253. {
  254.     OSErr io;            
  255.     /*     we should check the return code for errors */
  256.     io=FSWrite(refNum, &num, p);
  257.     if (io)
  258.         return(io);
  259.     io=SetEOF(refNum, num);
  260.     return(io);
  261. }
  262.  
  263. int ReadFile (short refNum, TEHandle textH)
  264.  
  265. {
  266.     char    buffer[256];
  267.     long    count;
  268.     OSErr        io;
  269.     
  270.     (**textH).selStart = 0;
  271.     (**textH).selEnd = (**textH).teLength;
  272.     TEDelete(textH);
  273.     GetEOF(refNum, &count);
  274.     if (count > 32767L)
  275.         return (999);
  276.     do {
  277.         count = 256;
  278.         io = FSRead(refNum, &count, &buffer);
  279.         TEInsert(&buffer, count, textH);
  280.     } while (io==noErr);
  281.     return (io == eofErr);
  282. }
  283.  
  284. int pStrCopy (StringPtr p1, StringPtr p2)
  285.  
  286. /* copies a pascal string from p1 to p2 */
  287. {
  288.     register int len = *p1;    // added asignment
  289.     
  290.     *(p2++) = *(p1++);            // added parens
  291.     while (--len>=0) *(p2++)=*(p1++);    // added parens
  292.     return 0; // should be void fn!?
  293. }
  294.  
  295.  
  296. int FileError(Str255 s, Str255 f)
  297.  
  298. {
  299.     ParamText(s, f,"\p", "\p");
  300.     Alert(ErrorAlert, 0L);
  301.     return 0; // should be void fn!?
  302. }
  303.  
  304.  
  305.  
  306. pascal void ScrollProc (ControlHandle theControl, short theCode);
  307.  
  308.  
  309. void PreInitWindows(void)
  310. {
  311.     if (TextEditWindow == 0)
  312.     {
  313.         SetUpWindows();
  314.         HideWindow(TextEditWindow);    /* just in case it's already visible */
  315.     }
  316. }
  317.  
  318. int SetUpWindows(void)
  319. {
  320.     Rect    viewRect;
  321.     Rect    vScrollRect;
  322.  
  323.     SetPort((TextEditWindow = GetNewWindow(windowID, &wRecord, (WindowPtr) -1L)));
  324.     TextFont(monaco);
  325.     TextSize(9);
  326.     vScrollRect = (*TextEditWindow).portRect;
  327.     vScrollRect.left = vScrollRect.right-15;
  328.     vScrollRect.right += 1;
  329.     vScrollRect.bottom -= 14;
  330.     vScrollRect.top -= 1;
  331.     vScroll = NewControl( TextEditWindow, &vScrollRect, "\p", 1, 0, 0, 0,
  332.         scrollBarProc, 0L);
  333.  
  334.     viewRect = qd.thePort->portRect;
  335.     viewRect.right -= SBarWidth;
  336.     viewRect.bottom -= SBarWidth;
  337.     InsetRect(&viewRect, 4, 4);
  338.     TEH = TENew(&viewRect, &viewRect);
  339.     SetView((WindowPtr) qd.thePort);
  340.     dirty = 0;
  341.     return 0; // should be void fn!?
  342. }
  343.  
  344.  
  345. int AdjustText (void)
  346.  
  347. {
  348.     int        oldScroll, newScroll, delta;
  349.     
  350.     oldScroll = (**TEH).viewRect.top - (**TEH).destRect.top;
  351.     newScroll = GetCtlValue(vScroll) * (**TEH).lineHeight;
  352.     delta = oldScroll - newScroll;
  353.     if (delta != 0)
  354.       TEScroll(0, delta, TEH);
  355.     SetVScroll();
  356.     return 0; // should be void fn!?
  357. }
  358.  
  359.  
  360. int SetVScroll(void)
  361. {
  362.     register int    n;
  363.     
  364.     n = (**TEH).nLines-linesInFolder;
  365.  
  366.     if ((**TEH).teLength > 0 && (*((**TEH).hText))[(**TEH).teLength-1]=='\r')
  367.         n++;
  368.  
  369.     SetCtlMax(vScroll, n > 0 ? n : 0);
  370.     return 0; // should be void fn!?
  371. }
  372.  
  373. int ShowSelect (void)
  374.  
  375. {
  376.     register    int        topLine, bottomLine, theLine;
  377.     
  378.     SetVScroll();
  379.     AdjustText();
  380.     
  381.     topLine = GetCtlValue(vScroll);
  382.     bottomLine = topLine + linesInFolder;
  383.     
  384.     if ((**TEH).selStart < (**TEH).lineStarts[topLine] ||
  385.             (**TEH).selStart >= (**TEH).lineStarts[bottomLine]) {
  386.         for (theLine = 0; (**TEH).selStart >= (**TEH).lineStarts[theLine]; theLine++)
  387.             ;
  388.         SetCtlValue(vScroll, theLine - linesInFolder / 2);
  389.         AdjustText();
  390.     }
  391.     return 0; // should be void fn!?
  392. }
  393.  
  394. int SetView (WindowPtr w)
  395.  
  396. {
  397.     (**TEH).viewRect = w->portRect;
  398.     (**TEH).viewRect.right -= SBarWidth;
  399.     (**TEH).viewRect.bottom -= SBarWidth;
  400.     InsetRect(&(**TEH).viewRect, 4, 4);
  401.  
  402.     linesInFolder = ((**TEH).viewRect.bottom-(**TEH).viewRect.top)/(**TEH).lineHeight;
  403.     (**TEH).viewRect.bottom = (**TEH).viewRect.top + (**TEH).lineHeight*linesInFolder;
  404.     (**TEH).destRect.right = (**TEH).viewRect.right;
  405.     TECalText(TEH);
  406.     return 0; // should be void fn!?
  407. }
  408.  
  409. int UpdateWindow (WindowPtr theWindow)
  410.  
  411. {
  412.     GrafPtr    savePort;
  413.     
  414.     GetPort(&savePort);
  415.     SetPort(theWindow);
  416.  
  417.     BeginUpdate(theWindow);
  418.     EraseRect(&theWindow->portRect);
  419.     DrawControls(theWindow);
  420.     DrawGrowIcon(theWindow);
  421.     TEUpdate(&theWindow->portRect, TEH);
  422.     EndUpdate(theWindow);
  423.  
  424.     SetPort(savePort);
  425.     return 0; // should be void fn!?
  426. }
  427.  
  428.  
  429.  
  430.  
  431. pascal void ScrollProc (ControlHandle theControl, short theCode)
  432. {
  433.     int    pageSize;
  434.     int    scrollAmt;
  435.     int oldCtl;
  436.     
  437.     if (theCode == 0)
  438.         return ;
  439.     
  440.     pageSize = ((**TEH).viewRect.bottom-(**TEH).viewRect.top) / 
  441.             (**TEH).lineHeight - 1;
  442.             
  443.     switch (theCode) {
  444.         case inUpButton: 
  445.             scrollAmt = -1;
  446.             break;
  447.         case inDownButton: 
  448.             scrollAmt = 1;
  449.             break;
  450.         case inPageUp: 
  451.             scrollAmt = -pageSize;
  452.             break;
  453.         case inPageDown: 
  454.             scrollAmt = pageSize;
  455.             break;
  456.     }
  457.  
  458.     oldCtl = GetCtlValue(theControl);
  459.     SetCtlValue(theControl, oldCtl+scrollAmt);
  460.  
  461.     AdjustText();
  462. }
  463.  
  464. int DoContent(WindowPtr theWindow, EventRecord *theEvent)
  465.  
  466. {
  467.     short            cntlCode;
  468.     ControlHandle     theControl;
  469.     GrafPtr            savePort;
  470.     
  471.     GetPort(&savePort);
  472.     SetPort(theWindow);
  473.  
  474.     GlobalToLocal(&theEvent->where);
  475.     if ((cntlCode = FindControl(theEvent->where, theWindow, &theControl)) == 0) {
  476.         if (PtInRect(theEvent->where, &(**TEH).viewRect))
  477.             TEClick(theEvent->where, (theEvent->modifiers & shiftKey)!=0, TEH);
  478.     } else if (cntlCode == inThumb) {
  479.         TrackControl(theControl, theEvent->where, 0L);
  480.         AdjustText();
  481.     } else
  482.         TrackControl(theControl, theEvent->where, (ProcPtr)&ScrollProc);
  483.  
  484.     SetPort(savePort);
  485.     return 0; // should be void fn!?
  486. }
  487.  
  488. void MyGrowWindow(WindowPtr w, Point p)
  489.  
  490. {
  491.     GrafPtr    savePort;
  492.     long    theResult;
  493.     Rect    oldHorizBar;
  494.     Rect     r;
  495.     
  496.     GetPort(&savePort);
  497.     SetPort(w);
  498.     
  499.     oldHorizBar = w->portRect;
  500.     oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
  501.  
  502.     SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom);
  503.     theResult = GrowWindow(w, p, &r);
  504.     if (theResult == 0)
  505.       return;
  506.     SizeWindow( w, LoWord(theResult), HiWord(theResult), false);
  507.  
  508.     get_WindowPos(w, &file_settings->srcWind_pos);                // added [esp]
  509. //    file_settings->src_width = LoWord(theResult);    -- removed [esp]
  510. //    file_settings->src_height = HiWord(theResult);    -- removed [esp]
  511.  
  512. //    WriteFileSettings();        -- moved to MyCloseWindow [esp]
  513.     InvalRect(&w->portRect);
  514.     
  515.     SetView(w);
  516.  
  517.     EraseRect(&oldHorizBar);
  518.     
  519.     MoveControl(vScroll, w->portRect.right - SBarWidth, w->portRect.top-1);
  520.     SizeControl(vScroll, SBarWidth+1, w->portRect.bottom - w->portRect.top-(SBarWidth-2));
  521.     r = (**vScroll).contrlRect;
  522.     ValidRect(&r);
  523.  
  524.  
  525.     SetVScroll();
  526.     AdjustText();
  527.     
  528.     SetPort(savePort);
  529. }
  530.  
  531.  
  532.  
  533. int CloseMyWindow(void)
  534. {
  535.     window_visible = FALSE;
  536.     HideWindow(TextEditWindow);
  537.     TESetSelect(0, (**TEH).teLength, TEH);
  538.     TEDelete(TEH);
  539.     SetVScroll();
  540.     SetUpFiles();
  541.     WriteFileSettings();    /* Save window position */    // added [esp]
  542.     CloseFileSettings();                                // added [esp]
  543.     return 0; // should be void fn!?
  544. }
  545.  
  546.  
  547.  
  548. #define    ours(w)        ((TextEditWindow != NULL) && (w == TextEditWindow))
  549.  
  550.  
  551.  
  552. PleaseWait()
  553. {
  554.     SetCursor(&waitCursor);
  555. }
  556.  
  557. main_init() 
  558. {
  559.     TextEditWindow = 0;
  560.     SetUpFiles();
  561.     SetUpCursors();
  562.     PreInitWindows();
  563. }
  564.  
  565.  
  566.  
  567. int DoEditMouseDown (int windowPart, WindowPtr whichWindow, EventRecord *myEvent)
  568.  
  569. {
  570.     switch (windowPart) {
  571.         case inGoAway:
  572.             if (ours(whichWindow) && (POV_running == 0))
  573.                 if (TrackGoAway(TextEditWindow, myEvent->where))
  574.                     DoFile(fmn_close);
  575.             break;
  576.  
  577.         case inDrag:
  578.             if (ours(whichWindow))
  579.             {    // added [esp]
  580.                 DragWindow(whichWindow, myEvent->where, &dragRect);
  581.                 get_WindowPos(whichWindow, &file_settings->srcWind_pos);    // added [esp]
  582.             }    // added [esp]
  583.             break;
  584.  
  585.         case inGrow:
  586.             if (ours(whichWindow))
  587.                 MyGrowWindow(whichWindow, myEvent->where);
  588.             break;
  589.  
  590.         case inContent:
  591.             if (whichWindow != FrontWindow())
  592.                 SelectWindow(whichWindow);
  593.             else if (ours(whichWindow))
  594.                 DoContent(whichWindow, myEvent);
  595.             break;
  596.     }
  597.     return 0; // should be void fn!?
  598. }
  599.  
  600.  
  601.  
  602.  
  603.  
  604. int MaintainCursor(void)
  605. {
  606.     Point        pt;
  607.     WindowPeek    wPtr;
  608.     GrafPtr        savePort;
  609.     
  610.     if (ours((WindowPtr)(wPtr=(WindowPeek)FrontWindow()))) {
  611.         GetPort(&savePort);
  612.         SetPort((GrafPtr)wPtr);
  613.         GetMouse(&pt);
  614.         if (PtInRect(pt, &(**TEH).viewRect ) )
  615.             SetCursor( &editCursor);
  616.         else SetCursor(&qd.arrow);
  617.         SetPort(savePort);
  618.     }
  619.     return 0; // should be void fn!?
  620. }
  621.  
  622.  
  623.  
  624. int SetUpCursors(void)
  625. {
  626.     CursHandle    hCurs;
  627.     
  628.     hCurs = GetCursor(1);
  629.     editCursor = **hCurs;
  630.     hCurs = GetCursor(watchCursor);
  631.     waitCursor = **hCurs;
  632.     return 0; // should be void fn!?
  633. }
  634.  
  635. #define topMargin 20
  636. #define leftMargin 20
  637. #define bottomMargin 20
  638. #define tabChar    ((char)'\t')
  639.  
  640. static    THPrint    hPrint = NULL;
  641. static    int        tabWidth;
  642.  
  643.  
  644.  
  645.     /**
  646.      **        Prototypes for private functions.
  647.      **        (They really should be static.)
  648.      **
  649.      **/
  650.  
  651. int    CheckPrintHandle(void);
  652. int MyDrawText(char *p, int count);
  653. int PrDoc(char **hText, long count, THPrint hPrint, int font, int size);
  654. int HowMany(void);
  655.  
  656.  
  657. CheckPrintHandle()
  658. {
  659.     if (hPrint==NULL) 
  660.         PrintDefault(hPrint = (TPrint **) NewHandle(sizeof( TPrint)));
  661. }
  662.  
  663. DoPageSetUp()
  664. {
  665.     PrOpen();
  666.     CheckPrintHandle();
  667.     if (PrStlDialog(hPrint)) ;
  668.     PrClose();
  669. }
  670.  
  671.  
  672. MyDrawText(char    *p, int count)
  673. {
  674.     register char    *p1, *p2;
  675.     int                len;
  676.     Point            pt;
  677.  
  678.     p1 = p;
  679.     p2 = p+count;
  680.     while (p<p2) {
  681.         while ((p1<p2) && (*p1 !=tabChar)) *p1++;
  682.         if ((len=p1-p)>0) DrawText(p, 0, p1-p);
  683.         if (*p1==tabChar) {
  684.             GetPen(&pt);
  685.             Move((tabWidth-(pt.h-leftMargin)%tabWidth), 0);
  686.             *p1++;
  687.         }
  688.         p = p1;
  689.     }
  690. }
  691.  
  692. PrDoc (char **hText, long count, THPrint hPrint, int font, int size)
  693. {
  694.     register int     line = 0;
  695.     register int     lastLineOnPage = 0;
  696.     int                length;
  697.     Rect             printRect;
  698.     int             linesPerPage;
  699.     int             lineBase;
  700.     int             lineHeight;
  701.     register char     *ptr, *p1;
  702.     FontInfo        info;
  703.     TPPrPort        printPort;
  704.  
  705.     printPort = PrOpenDoc(hPrint, 0L, 0L);
  706.     SetPort((GrafPtr)printPort);
  707.     TextFont(font);
  708.     TextSize(size);
  709.     printRect = (**hPrint).prInfo.rPage;
  710.     GetFontInfo(&info);
  711.     lineHeight = info.leading+info.ascent+info.descent;
  712.     linesPerPage = 
  713.         (printRect.bottom-printRect.top-topMargin-bottomMargin)/lineHeight;
  714.     HLock(hText);
  715.     ptr = p1 = (*hText);
  716.     do {
  717.         PrOpenPage(printPort, 0L);
  718.         lastLineOnPage += linesPerPage;
  719.         MoveTo( printRect.left+leftMargin, 
  720.             (lineBase = printRect.top+lineHeight) );
  721.         do {
  722.             /* PrintLine: */
  723.             while ((ptr<=(*hText)+count) && (*ptr++ != (char)'\r')) ;
  724.             if ((length=(int)(ptr-p1)-1)>0)
  725.                 MyDrawText(p1, length);
  726.             MoveTo( printRect.left+leftMargin, (lineBase += lineHeight));
  727.             p1 = ptr;
  728.         } while ((++line != lastLineOnPage) && (ptr<(*hText)+count));
  729.         PrClosePage(printPort);
  730.     } while (ptr<(*hText)+count);
  731.     HUnlock(hText);
  732.     PrCloseDoc(printPort);
  733. }
  734.  
  735. PrintText(char    **hText, long length, GrafPtr gp, int tabPixels)
  736.  
  737. {
  738.     GrafPtr        savePort;
  739.     TPrStatus    prStatus;
  740.     int            copies;
  741.     
  742.     PrOpen();
  743.     CheckPrintHandle();
  744.     tabWidth = tabPixels;
  745.     SetCursor(&qd.arrow);
  746.     if (PrJobDialog(hPrint) != 0) {
  747.         PleaseWait();
  748.         GetPort(&savePort);
  749.         for (copies=HowMany(); copies>0; copies--) {
  750.             PrDoc (hText, length, hPrint, (*gp).txFont, (*gp).txSize);
  751.             PrPicFile(hPrint, 0L, 0L, 0L, &prStatus);
  752.         }
  753.         SetPort(savePort);
  754.     }
  755.     PrClose();
  756. }
  757.  
  758. int HowMany(void)
  759. {
  760.     return( ((**hPrint).prJob.bJDocLoop==bDraftLoop) ? 
  761.                 (**hPrint).prJob.iCopies : 1 );
  762. }
  763.  
  764.  
  765.